home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume10 / logo / part03 < prev    next >
Encoding:
Internet Message Format  |  1987-06-23  |  47.4 KB

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v10i023: Logo interpreter for Unix, Part03/06
  5. Message-ID: <449@uunet.UU.NET>
  6. Date: 24 Jun 87 20:21:46 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 2537
  9. Approved: rs@uunet.uu.net
  10.  
  11. Submitted by: Brian Harvey <bh@mit-amt>
  12. Mod.Sources: Volume 10, Number 23
  13. Archive-Name: logo/Part03
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 3 (of 6)."
  22. # Contents:  logoaux.c logoop.c logoproc.c turtle.c
  23. # Wrapped by rsalz@pineapple.bbn.com on Wed Jun 24 14:26:57 1987
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f logoaux.c -a "${1}" != "-c" ; then 
  26.   echo shar: Will not over-write existing file \"logoaux.c\"
  27. else
  28. echo shar: Extracting \"logoaux.c\" \(11138 characters\)
  29. sed "s/^X//" >logoaux.c <<'END_OF_logoaux.c'
  30. X
  31. X/*    This file contains a miscellany of functions for LOGO, both
  32. X * primary implementation of LOGO operations and commands, and also various
  33. X * other functions for maintaining the overhead of the interpreter (variable
  34. X * storage, function calls, etc.)
  35. X *
  36. X *    Copyright (C) 1979, The Children's Museum, Boston, Mass.
  37. X *    Written by Douglas B. Klunder
  38. X */
  39. X
  40. X#include "logo.h"
  41. X#include <sgtty.h>
  42. X#include <setjmp.h>
  43. Xextern jmp_buf yerrbuf;
  44. Xint tvec[2] ={0,0};
  45. Xextern int yychar,yylval,yyline;
  46. Xextern int topf,errtold,flagquit;
  47. Xextern FILE *ofile;
  48. Xextern char *ostring;
  49. Xextern char *getbpt;
  50. Xextern char charib;
  51. Xextern int pflag,letflag;
  52. Xextern int currtest;
  53. Xstruct runblock *thisrun = NULL;
  54. Xextern struct plist *pcell;    /* for PAUSE */
  55. Xextern struct stkframe *fbr;
  56. X#ifdef PAUSE
  57. Xextern int pauselev,psigflag;
  58. X#endif
  59. X
  60. Xtyobj(text)
  61. Xregister struct object *text;
  62. X{
  63. X    register struct object *temp;
  64. X    char str[30];
  65. X
  66. X    if (text==0) return;
  67. X    switch (text->obtype) {
  68. X        case CONS:
  69. X            for (temp = text; temp; temp = temp->obcdr) {
  70. X                fty1(temp->obcar);
  71. X                if(temp->obcdr) putc1(' ');
  72. X            }
  73. X            break;
  74. X        case STRING:
  75. X            sputs(text->obstr);
  76. X            break;
  77. X        case INT:
  78. X            sprintf(str,FIXFMT,text->obint);
  79. X            sputs(str);
  80. X            break;
  81. X        case DUB:
  82. X            sprintf(str,"%g",text->obdub);
  83. X            if (!index(str,'.')) strcat(str,".0");
  84. X            sputs(str);
  85. X            break;
  86. X    }
  87. X}
  88. X
  89. Xfty1(text)
  90. Xregister struct object *text;
  91. X{
  92. X    if (listp(text)) {
  93. X        putc1('[');
  94. X        tyobj(text);
  95. X        putc1(']');
  96. X    } else tyobj(text);
  97. X}
  98. X
  99. Xfillbuf(text)    /* Logo TYPE */
  100. Xregister struct object *text;
  101. X{
  102. X    tyobj(text);
  103. X    mfree(text);
  104. X}
  105. X
  106. Xstruct object *cmprint(arg)
  107. Xstruct object *arg;
  108. X{
  109. X    fillbuf(arg);
  110. X    putchar('\n');
  111. X    return ((struct object *)(-1));
  112. X}
  113. X
  114. Xstruct object *cmtype(arg)
  115. Xstruct object *arg;
  116. X{
  117. X    fillbuf(arg);
  118. X    return ((struct object *)(-1));
  119. X}
  120. X
  121. Xstruct object *cmfprint(arg)
  122. Xstruct object *arg;
  123. X{
  124. X    fty1(arg);
  125. X    putchar('\n');
  126. X    mfree(arg);
  127. X    return ((struct object *)(-1));
  128. X}
  129. X
  130. Xstruct object *cmftype(arg)
  131. Xstruct object *arg;
  132. X{
  133. X    fty1(arg);
  134. X    mfree(arg);
  135. X    return ((struct object *)(-1));
  136. X}
  137. X
  138. Xsetfile(file)
  139. Xregister struct object *file;
  140. X{
  141. X    file = numconv(file,"File command");
  142. X    if (!intp(file)) ungood("File command",file);
  143. X    ofile = (FILE *)((int)(file->obint));
  144. X    mfree(file);
  145. X}
  146. X
  147. Xfileprint(file,text)
  148. Xregister struct object *file,*text;
  149. X{
  150. X    setfile(file);
  151. X    fillbuf(text);
  152. X    fputc('\n',ofile);
  153. X    ofile = NULL;
  154. X}
  155. X
  156. Xfilefprint(file,text)
  157. Xregister struct object *file,*text;
  158. X{
  159. X    setfile(file);
  160. X    fty1(text);
  161. X    mfree(text);
  162. X    fputc('\n',ofile);
  163. X    ofile = NULL;
  164. X}
  165. X
  166. Xfiletype(file,text)
  167. Xregister struct object *file,*text;
  168. X{
  169. X    setfile(file);
  170. X    fillbuf(text);
  171. X    ofile = NULL;
  172. X}
  173. X
  174. Xfileftype(file,text)
  175. Xstruct object *file,*text;
  176. X{
  177. X    setfile(file);
  178. X    fty1(text);
  179. X    mfree(text);
  180. X    ofile = NULL;
  181. X}
  182. X
  183. Xstruct object *openfile(name,type)
  184. Xregister struct object *name;
  185. Xregister char *type;
  186. X{
  187. X    FILE *fildes;
  188. X
  189. X    if (!stringp(name)) ungood("Open file",name);
  190. X    fildes = fopen(name->obstr,type);
  191. X    if (!fildes) {
  192. X        pf1("Can't open file %l.\n",name);
  193. X        errhand();
  194. X    }
  195. X    mfree(name);
  196. X    return(localize(objint((FIXNUM)((int)fildes))));
  197. X}
  198. X
  199. Xstruct object *loread(arg)
  200. Xstruct object *arg;
  201. X{
  202. X    return(openfile(arg,"r"));
  203. X}
  204. X
  205. Xstruct object *lowrite(arg)
  206. Xstruct object *arg;
  207. X{
  208. X    return(openfile(arg,"w"));
  209. X}
  210. X
  211. Xstruct object *callunix(cmd)
  212. Xregister struct object *cmd;
  213. X{
  214. X    register struct object *str;
  215. X
  216. X    str = stringform(cmd);
  217. X    system(str->obstr);
  218. X    mfree(str);
  219. X    mfree(cmd);
  220. X    return ((struct object *)(-1));
  221. X}
  222. X
  223. Xstruct object *fileclose(file)
  224. Xregister struct object *file;
  225. X{
  226. X    setfile(file);
  227. X    fclose(ofile);
  228. X    ofile = NULL;
  229. X    return ((struct object *)(-1));
  230. X}
  231. X
  232. Xstruct object *fileread(file,how)
  233. Xregister struct object *file;
  234. Xint how; /* 0 for fileread (returns list), 1 for fileword (returns str) */
  235. X{
  236. X    char str[200];
  237. X    register struct object *x;
  238. X    char *svgbpt;
  239. X    char c;
  240. X
  241. X    setfile(file);
  242. X    fgets(str,200,ofile);
  243. X    if (feof(ofile)) {
  244. X        ofile = NULL;
  245. X        if (how) return((struct object *)0);
  246. X        return(localize(objcpstr("")));
  247. X    }
  248. X    ofile = NULL;
  249. X    if (how) {
  250. X        str[strlen(str)-1] = '\0';
  251. X        return(localize(objcpstr(str)));
  252. X    }
  253. X    str[strlen(str)-1] = ']';
  254. X    c = charib;
  255. X    charib = 0;
  256. X    svgbpt = getbpt;
  257. X    getbpt = str;
  258. X    x = makelist();
  259. X    getbpt = svgbpt;
  260. X    charib = c;
  261. X    return(x);
  262. X}
  263. X
  264. Xstruct object *lfread(arg)
  265. Xstruct object *arg;
  266. X{
  267. X    return(fileread(arg,0));
  268. X}
  269. X
  270. Xstruct object *lfword(arg)
  271. Xstruct object *arg;
  272. X{
  273. X    return(fileread(arg,1));
  274. X}
  275. X
  276. Xstruct object *lsleep(tim)    /* wait */
  277. Xregister struct object *tim;
  278. X{
  279. X    int itim;
  280. X
  281. X    tim = numconv(tim,"Wait");
  282. X    if (intp(tim)) itim = tim->obint;
  283. X    else itim = tim->obdub;
  284. X    mfree(tim);
  285. X    sleep(itim);
  286. X    return ((struct object *)(-1));
  287. X}
  288. X
  289. Xstruct object *input(flag)
  290. Xint flag;    /* 0 for readlist, 1 for request */
  291. X{
  292. X    int len;
  293. X    char s[512];
  294. X    register struct object *x;
  295. X    char *svgbpt;
  296. X    char c;
  297. X
  298. X    if (flag) putchar('?');
  299. X    fflush(stdout);
  300. X    len = read(0,s,512);
  301. X    if (len <= 0) len = 1;
  302. X    s[len-1]=']';
  303. X    c = charib;
  304. X    charib = 0;
  305. X    svgbpt = getbpt;
  306. X    getbpt = s;
  307. X    x = makelist();
  308. X    getbpt = svgbpt;
  309. X    charib = c;
  310. X    return (x);
  311. X}
  312. X
  313. Xstruct object *readlist() {
  314. X    return(input(0));
  315. X}
  316. X
  317. Xstruct object *request() {
  318. X    return(input(1));
  319. X}
  320. X
  321. Xstruct object *ltime()        /* LOGO time */
  322. X{
  323. X    char ctim[50];
  324. X    register struct object *x;
  325. X    char *svgbpt;
  326. X    char c;
  327. X
  328. X    time(tvec);
  329. X    strcpy(ctim,ctime(tvec));
  330. X    ctim[strlen(ctim)-1]=']';
  331. X    c = charib;
  332. X    charib = 0;
  333. X    svgbpt = getbpt;
  334. X    getbpt = ctim;
  335. X    x = makelist();
  336. X    getbpt = svgbpt;
  337. X    charib = c;
  338. X    return(x);
  339. X}
  340. X
  341. Xdorun(arg,num)
  342. Xstruct object *arg;
  343. XFIXNUM num;
  344. X{
  345. X    register struct object *str;
  346. X    register struct runblock *rtemp;
  347. X
  348. X    rtemp = (struct runblock *)ckmalloc(sizeof(struct runblock));
  349. X    if (num != 0) {
  350. X        rtemp->rcount = num;
  351. X        rtemp->rupcount = 0;
  352. X    } else {
  353. X        rtemp->rcount = 1;    /* run or if, not repeat */
  354. X         if (thisrun)
  355. X             rtemp->rupcount = thisrun->rupcount - 1;
  356. X         else
  357. X             rtemp->rupcount = 0;
  358. X    }
  359. X    rtemp->roldyyc = yychar;
  360. X    rtemp->roldyyl = yylval;
  361. X    rtemp->roldline = yyline;
  362. X    rtemp->svbpt = getbpt;
  363. X    rtemp->svpflag = pflag;
  364. X    rtemp->svletflag = letflag;
  365. X    rtemp->svch = charib;
  366. X    if (arg == (struct object *)(-1)) {    /* PAUSE */
  367. X        rtemp->str = (struct object *)(-1);
  368. X    } else {
  369. X        str = stringform(arg);
  370. X        mfree(arg);
  371. X        strcat(str->obstr,"\n");
  372. X        rtemp->str = globcopy(str);
  373. X        mfree(str);
  374. X    }
  375. X    rtemp->rprev = thisrun;
  376. X    thisrun = rtemp;
  377. X    rerun();
  378. X}
  379. X
  380. Xrerun() {
  381. X    yychar = -1;
  382. X    pflag = 0;
  383. X    letflag = 0;
  384. X    charib = '\0';
  385. X    thisrun->rupcount++;
  386. X    if (thisrun->str == (struct object *)(-1))    /* PAUSE */
  387. X        getbpt = 0;
  388. X    else
  389. X        getbpt = thisrun->str->obstr;
  390. X}
  391. X
  392. Xunrun() {
  393. X    register struct runblock *rtemp;
  394. X
  395. X    yychar = thisrun->roldyyc;
  396. X    yylval = thisrun->roldyyl;
  397. X    yyline = thisrun->roldline;
  398. X    getbpt = thisrun->svbpt;
  399. X    pflag = thisrun->svpflag;
  400. X    letflag = thisrun->svletflag;
  401. X    charib = thisrun->svch;
  402. X    if (thisrun->str != (struct object *)(-1))    /* PAUSE */
  403. X        lfree(thisrun->str);
  404. X    rtemp = thisrun;
  405. X    thisrun = thisrun->rprev;
  406. X    JFREE(rtemp);
  407. X}
  408. X
  409. Xdorep(count,cmd)
  410. Xstruct object *count,*cmd;
  411. X{
  412. X    FIXNUM icount;
  413. X
  414. X    count = numconv(count,"Repeat");
  415. X    if (intp(count)) icount = count->obint;
  416. X    else icount = count->obdub;
  417. X    if (icount < (FIXNUM)0) ungood("Repeat",count);
  418. X    if (icount == (FIXNUM)0) {
  419. X        mfree(cmd);
  420. X        cmd = 0;
  421. X        icount++;
  422. X    }
  423. X    dorun(cmd,icount);
  424. X    mfree(count);
  425. X}
  426. X
  427. Xstruct object *repcount() {
  428. X    if (!thisrun) {
  429. X        puts("Repcount outside repeat.");
  430. X        errhand();
  431. X    }
  432. X    return(localize(objint(thisrun->rupcount)));
  433. X}
  434. X
  435. X#ifdef PAUSE
  436. Xdopause() {
  437. X    register struct plist *opc;
  438. X
  439. X    if (pflag || getbpt) {
  440. X        printf("Pausing");
  441. X        opc = pcell;
  442. X        if (fbr && fbr->oldline==-1) {
  443. X            opc=fbr->prevpcell;
  444. X        }
  445. X        if (opc&&!topf) printf(" at line %d in procedure %s",yyline,
  446. X                opc->procname->obstr);
  447. X        printf("\n");
  448. X        pauselev++;
  449. X    }
  450. X    if (psigflag) {
  451. X        psigflag = 0;
  452. X#ifdef EUNICE
  453. X        yyprompt();
  454. X#endif
  455. X    }
  456. X    if (pflag || getbpt)
  457. X        dorun((struct object *)(-1),(FIXNUM)0);
  458. X}
  459. X
  460. Xunpause() {
  461. X    if (pauselev > 0) {
  462. X        pauselev--;
  463. X        unrun();
  464. X    }
  465. X}
  466. X#endif
  467. X
  468. Xerrhand()    /* do error recovery, then pop out to outer level */
  469. X{
  470. X    errtold++;
  471. X    flagquit = 0;
  472. X    onintr(errrec,1);
  473. X#ifdef PAUSE
  474. X    longjmp(yerrbuf,9);
  475. X#else
  476. X    ltopl();
  477. X#endif
  478. X}
  479. X
  480. Xnullfn()
  481. X{
  482. X}
  483. X
  484. Xreadlin(fd,buf)        /* read a line from file */
  485. Xregister FILDES fd;
  486. Xregister char *buf;
  487. X{
  488. X    register char *i;
  489. X
  490. X    for (i = buf; *(i-1) != '\n'; i++) read(fd,i,1);
  491. X}
  492. X
  493. Xmakeup(str)
  494. Xregister char *str;
  495. X{
  496. X    register char ch;
  497. X
  498. X    while (ch = *str) {
  499. X        if (ch >= 'a' && ch <= 'z') *str = ch-040;
  500. X        str++;
  501. X    }
  502. X}
  503. X
  504. Xstruct object *cbreak(ostr)
  505. Xregister struct object *ostr;
  506. X{
  507. X    struct sgttyb sgt;
  508. X    register char *str;
  509. X
  510. X#ifdef CBREAK
  511. X    if (!stringp(ostr)) ungood("Cbreak",ostr);
  512. X    str = ostr->obstr;
  513. X    makeup(str);
  514. X    if (strcmp(str,"ON") && strcmp(str,"OFF")) {
  515. X        puts("cbreak input must be \"on or \"off");
  516. X        errhand();
  517. X    }
  518. X    gtty(0,&sgt);
  519. X    if (!strcmp(str,"ON")) {
  520. X        sgt.sg_flags |= CBREAK;
  521. X        sgt.sg_flags &= ~ECHO;
  522. X    } else {
  523. X        sgt.sg_flags &= ~CBREAK;
  524. X        sgt.sg_flags |= ECHO;
  525. X    }
  526. X    stty(0,&sgt);
  527. X    mfree(ostr);
  528. X    return ((struct object *)(-1));
  529. X#else
  530. X    printf("No CBREAK on this system.\n");
  531. X    errhand();    /* Such as V6 or Idris */
  532. X#endif
  533. X}
  534. X
  535. Xcboff()
  536. X{
  537. X    struct sgttyb sgt;
  538. X
  539. X#ifdef CBREAK
  540. X    gtty(0,&sgt);
  541. X    sgt.sg_flags &= ~CBREAK;
  542. X    sgt.sg_flags |= ECHO;
  543. X    stty(0,&sgt);
  544. X#endif
  545. X}
  546. X
  547. Xstruct object *readchar()
  548. X{
  549. X    char s[2];
  550. X
  551. X    fflush(stdout);
  552. X    read(0,s,1);
  553. X    s[1] = '\0';
  554. X    return(localize(objcpstr(s)));
  555. X}
  556. X
  557. Xstruct object *keyp()
  558. X{
  559. X#ifdef TIOCEMPTY
  560. X    int i;
  561. X
  562. X    fflush(stdout);
  563. X    ioctl(0,TIOCEMPTY,&i);
  564. X    if (i)
  565. X        return(true());
  566. X    else
  567. X#else 
  568. X#ifdef FIONREAD
  569. X    long i;
  570. X
  571. X    fflush(stdout);
  572. X    ioctl(0,FIONREAD,&i);
  573. X    if (i)
  574. X        return(true());
  575. X    else
  576. X#endif
  577. X#endif
  578. X        return(false());
  579. X}
  580. X
  581. Xstruct object *settest(val)
  582. Xstruct object *val;
  583. X{
  584. X    if (obstrcmp(val,"true") && obstrcmp(val,"false")) ungood("Test",val);
  585. X    currtest = !obstrcmp(val,"true");
  586. X    mfree(val);
  587. X    return ((struct object *)(-1));
  588. X}
  589. X
  590. Xloflush() {
  591. X    fflush(stdout);
  592. X}
  593. X
  594. Xstruct object *cmoutput(arg)
  595. Xstruct object *arg;
  596. X{
  597. X    extern int endflag;
  598. X
  599. X#ifdef PAUSE
  600. X    if (!pflag && thisrun && thisrun->str==(struct object *)(-1))
  601. X        unpause();
  602. X#endif
  603. X    endflag = 1;
  604. X    return(arg);
  605. X}
  606. X
  607. X#ifdef SETCURSOR
  608. X
  609. Xint gotterm = 0;
  610. X
  611. X/* Termcap definitions */
  612. X
  613. Xchar    *UP,
  614. X    *CS,
  615. X    *CM,
  616. X    *CL,
  617. X    *BC,
  618. X    *padchar;
  619. X
  620. Xchar    PC = '\0';
  621. X
  622. Xshort ospeed;
  623. X
  624. Xchar    tspace[128];
  625. X
  626. Xchar **meas[] = {
  627. X    &CS, &CM, &CL, &UP, &BC, &padchar, 0
  628. X};
  629. X
  630. Xchar    tbuff[1024];
  631. X
  632. XgetTERM()
  633. X{
  634. X    char    *getenv();
  635. X    struct sgttyb tty;
  636. X    char    *ts="cscmclupbcpc";
  637. X    char    *termname = 0,
  638. X        *termp = tspace;
  639. X    int    i;
  640. X
  641. X    if (gotterm) return(gotterm);
  642. X
  643. X    if (gtty(1, &tty)) {
  644. X        ospeed = B1200;
  645. X    } else {
  646. X        tty.sg_flags &= ~ XTABS;
  647. X        ospeed = tty.sg_ospeed;
  648. X        stty(1,&tty);
  649. X    }
  650. X
  651. X    termname = getenv("TERM");
  652. X    if (termname == 0) {
  653. X        puts("No terminal in environment.");
  654. X        gotterm = -1;
  655. X        return(gotterm);
  656. X    }
  657. X
  658. X    if (tgetent(tbuff, termname) < 1) {
  659. X        pf1("No termcap entry for %s\n",termname);
  660. X        gotterm = -1;
  661. X        return(gotterm);
  662. X    }
  663. X
  664. X    for (i = 0; meas[i]; i++) {
  665. X        *(meas[i]) = (char *) tgetstr(ts, &termp);
  666. X        ts += 2;
  667. X    }
  668. X
  669. X    if (padchar) PC = *padchar;
  670. X
  671. X    gotterm = 1;
  672. X    return(gotterm);
  673. X}
  674. X
  675. Xextern int putch();
  676. X
  677. Xstruct object *clrtxt()
  678. X{
  679. X    if (getTERM() < 0) return;
  680. X    tputs(CL,24,putch);
  681. X    return ((struct object *)(-1));
  682. X}
  683. X
  684. Xstruct object *setcur(x,y)
  685. Xstruct object *x,*y;
  686. X{
  687. X    int ix,iy;
  688. X
  689. X    x=numconv(x,"Setcursorxy");
  690. X    y=numconv(y,"Setcursorxy");
  691. X    if (!intp(x)) ungood("Setcursorxy",x);
  692. X    if (!intp(y)) ungood("Setcursorxy",y);
  693. X    if (getTERM() > 0) {
  694. X        ix = x->obint;
  695. X        iy = y->obint;
  696. X        tputs(tgoto(CM,ix,iy),1,putch);
  697. X    }
  698. X    mfree(x);
  699. X    mfree(y);
  700. X    return ((struct object *)(-1));
  701. X}
  702. X
  703. X#endif SETCURSOR
  704. X
  705. END_OF_logoaux.c
  706. if test 11138 -ne `wc -c <logoaux.c`; then
  707.     echo shar: \"logoaux.c\" unpacked with wrong size!
  708. fi
  709. # end of overwriting check
  710. fi
  711. if test -f logoop.c -a "${1}" != "-c" ; then 
  712.   echo shar: Will not over-write existing file \"logoop.c\"
  713. else
  714. echo shar: Extracting \"logoop.c\" \(10685 characters\)
  715. sed "s/^X//" >logoop.c <<'END_OF_logoop.c'
  716. X
  717. X/*    Miscellaneous operations in LOGO.
  718. X *    Copyright (C) 1979, The Children's Museum, Boston, Mass.
  719. X *    Written by Douglas B. Klunder.
  720. X */
  721. X
  722. X#include "logo.h"
  723. X
  724. Xstruct object *true()
  725. X{
  726. X    return(localize(objcpstr("true")));
  727. X}
  728. X
  729. Xstruct object *false()
  730. X{
  731. X    return(localize(objcpstr("false")));
  732. X}
  733. X
  734. Xobstrcmp(obj,str)
  735. Xregister struct object *obj;
  736. Xchar *str;
  737. X{
  738. X    if (!stringp(obj)) return(1);
  739. X    return(strcmp(obj->obstr,str));
  740. X}
  741. X
  742. Xint truth(x)    /* used by if handler in logo.y */
  743. Xregister struct object *x;
  744. X{
  745. X    if (obstrcmp(x,"true") && obstrcmp(x,"false")) ungood("If",x);
  746. X    if (!obstrcmp(x,"true")) {
  747. X        mfree(x);
  748. X        return(1);
  749. X    } else {
  750. X        mfree(x);
  751. X        return(0);
  752. X    }
  753. X}
  754. X
  755. Xchar *mkstring(obj)
  756. Xregister struct object *obj;
  757. X{
  758. X    /* subroutine for several operations which treat numbers as words,
  759. X     * turn number into character string.
  760. X     * Note: obj must be known to be nonempty; result is ptr to static.
  761. X     */
  762. X
  763. X    register char *cp;
  764. X    static char str[30];
  765. X
  766. X    switch(obj->obtype) {
  767. X        case STRING:
  768. X            cp = obj->obstr;
  769. X            break;
  770. X        case INT:
  771. X            sprintf(str,FIXFMT,obj->obint);
  772. X            cp = str;
  773. X            break;
  774. X        case DUB:
  775. X            sprintf(str,"%g",obj->obdub);
  776. X            if (!index(str,'.')) strcat(str,".0");
  777. X            cp = str;
  778. X            break;
  779. X        default:    /* case CONS */
  780. X            return(0);    /* not a string, handle uplevel */
  781. X    }
  782. X    return(cp);
  783. X}
  784. X
  785. Xstruct object *and(x,y)        /* both */
  786. Xregister struct object *x,*y;
  787. X{
  788. X    if (obstrcmp(x,"true") && obstrcmp(x,"false")) ungood("Both",x);
  789. X    if (obstrcmp(y,"true") && obstrcmp(y,"false")) ungood("Both",y);
  790. X    if (!obstrcmp(x,"true")) {
  791. X        mfree(x);
  792. X        return(y);
  793. X    } else {
  794. X        mfree(y);
  795. X        return(x);
  796. X    }
  797. X}
  798. X
  799. Xstruct object *or(x,y)        /* either */
  800. Xregister struct object *x,*y;
  801. X{
  802. X    if (obstrcmp(x,"true") && obstrcmp(x,"false")) ungood("Either",x);
  803. X    if (obstrcmp(y,"true") && obstrcmp(y,"false")) ungood("Either",y);
  804. X    if (!obstrcmp(x,"true")) {
  805. X        mfree(y);
  806. X        return(x);
  807. X    } else {
  808. X        mfree(x);
  809. X        return(y);
  810. X    }
  811. X}
  812. X
  813. Xemptyp(x)    /* non-LOGO emptyp, returning 1 if empty, 0 if not. */
  814. Xregister struct object *x;
  815. X{
  816. X    if (x==0) return(1);
  817. X    switch (x->obtype) {
  818. X        case STRING:
  819. X            if (*(x->obstr)=='\0')    /* check for character */
  820. X                return(1);
  821. X        default:
  822. X            return(0);
  823. X    }
  824. X}
  825. X
  826. Xstruct object *lemp(x)        /* LOGO emptyp */
  827. Xregister struct object *x;
  828. X{
  829. X    if (emptyp(x)) {
  830. X        mfree(x);
  831. X        return(true());
  832. X    } else {
  833. X        mfree(x);
  834. X        return(false());
  835. X    }
  836. X}
  837. X
  838. Xstruct object *comp(x)        /* not */
  839. Xregister struct object *x;
  840. X{
  841. X    if (!obstrcmp(x,"true")) {
  842. X        mfree(x);
  843. X        return(false());
  844. X    } else if (!obstrcmp(x,"false")) {
  845. X        mfree(x);
  846. X        return(true());
  847. X    } else ungood("Not",x);
  848. X}
  849. X
  850. Xstruct object *lsentp(x)    /* LOGO sentencep */
  851. Xregister struct object *x;
  852. X{
  853. X    register struct object *y;
  854. X
  855. X    if (x==0) return(true());
  856. X    if (listp(x)) {
  857. X        /* BH 4/30/81 true only for a flat sentence,
  858. X           not a list of lists */
  859. X        for (y = x; y; y = y->obcdr)
  860. X            if (listp(y->obcar)) {
  861. X                mfree(x);
  862. X                return(false());
  863. X            }
  864. X        mfree(x);
  865. X        return(true());
  866. X    } else {
  867. X        mfree(x);
  868. X        return(false());
  869. X    }
  870. X}
  871. X
  872. Xstruct object *lwordp(x)    /* LOGO wordp */
  873. Xregister struct object *x;
  874. X{
  875. X    if (!listp(x)) {
  876. X        mfree(x);
  877. X        return(true());
  878. X    } else {
  879. X        mfree(x);
  880. X        return(false());
  881. X    }
  882. X}
  883. X
  884. Xstruct object *first(x)        /* first */
  885. Xregister struct object *x;
  886. X{
  887. X    register struct object *temp;
  888. X    register char *cp;
  889. X    char str[2];
  890. X
  891. X    if (emptyp(x)) ungood("First",x);
  892. X    if (cp = mkstring(x)) {
  893. X        str[0] = *cp;
  894. X        str[1] = '\0';
  895. X        mfree(x);
  896. X        return(localize(objcpstr(str)));
  897. X    } else {
  898. X        temp = x->obcar;
  899. X        localize(temp);
  900. X        mfree(x);
  901. X        return(temp);
  902. X    }
  903. X}
  904. X
  905. Xstruct object *butfir(x)        /* butfirst */
  906. Xregister struct object *x;
  907. X{
  908. X    register struct object *temp;
  909. X    register char *cp;
  910. X
  911. X    if (emptyp(x)) ungood("Butfirst",x);
  912. X    if (cp = mkstring(x)) {
  913. X        cp++;    /* skip first char */
  914. X        mfree(x);
  915. X        return(localize(objcpstr(cp)));
  916. X    } else {
  917. X        temp = x->obcdr;
  918. X        localize(temp);
  919. X        mfree(x);
  920. X        return(temp);
  921. X    }
  922. X}
  923. X
  924. Xstruct object *last(x)        /* last */
  925. Xregister struct object *x;
  926. X{
  927. X    register struct object *temp;
  928. X    register char *cp;
  929. X
  930. X    if (emptyp(x)) ungood("Last",x);
  931. X    if (cp = mkstring(x)) {
  932. X        mfree(x);
  933. X        return(localize(objcpstr(&cp[strlen(cp)-1])));
  934. X    } else {
  935. X        for(temp=x; temp->obcdr; temp=temp->obcdr) ;
  936. X        temp = temp->obcar;
  937. X        localize(temp);
  938. X        mfree(x);
  939. X        return(temp);
  940. X    }
  941. X}
  942. X
  943. Xstruct object *butlas(x)        /* butlast */
  944. Xregister struct object *x;
  945. X{
  946. X    register struct object *temp,*temp2,*ans;
  947. X    register char *cp;
  948. X
  949. X    if (emptyp(x)) ungood("Butlast",x);
  950. X    if (cp = mkstring(x)) {
  951. X        mfree(x);
  952. X        temp = objstr(ckmalloc(strlen(cp)));
  953. X        strncpy(temp->obstr,cp,strlen(cp)-1);
  954. X        (temp->obstr)[strlen(cp)-1] = '\0';
  955. X        return(localize(temp));
  956. X    } else {
  957. X        if ((x->obcdr)==0) {
  958. X            mfree(x);
  959. X            return(0);
  960. X        }
  961. X        temp2 = ans = globcons(0,0);
  962. X        for(temp=x; temp->obcdr->obcdr; temp=temp->obcdr) {
  963. X            temp2->obcar = globcopy(temp->obcar);
  964. X            temp2->obcdr = globcopy(globcons(0,0));
  965. X            temp2 = temp2->obcdr;
  966. X        }
  967. X        temp2->obcar = globcopy(temp->obcar);
  968. X        localize(ans);
  969. X        mfree(x);
  970. X        return(ans);
  971. X    }
  972. X}
  973. X
  974. Xstruct object *fput(x,y)
  975. Xregister struct object *x,*y;
  976. X{
  977. X    register struct object *z;
  978. X
  979. X    if(!listp(y)) {
  980. X        printf("Second input of fput must be a list.\n");
  981. X        errhand();
  982. X    }
  983. X    z = loccons(x,y);
  984. X    mfree(x);
  985. X    mfree(y);
  986. X    return(z);
  987. X}
  988. X
  989. Xstruct object *lput(x,y)
  990. Xstruct object *x,*y;
  991. X{
  992. X    register struct object *a,*b,*ans;
  993. X
  994. X    if (!listp(y)) {
  995. X        printf("Second input of lput must be a list.\n");
  996. X        errhand();
  997. X    }
  998. X    if (y == 0) {    /* 2nd input is empty list */
  999. X        b = loccons(x,0);
  1000. X        mfree(x);
  1001. X        return(b);
  1002. X    }
  1003. X    ans = a = loccons(0,0);
  1004. X    for (b=y; b; b=b->obcdr) {
  1005. X        a->obcar = globcopy(b->obcar);
  1006. X        a->obcdr = globcopy(globcons(0,0));
  1007. X        a = a->obcdr;
  1008. X    }
  1009. X    a->obcar = globcopy(x);
  1010. X    mfree(x);
  1011. X    mfree(y);
  1012. X    return(ans);
  1013. X}
  1014. X
  1015. Xstruct object *list(x,y)
  1016. Xstruct object *x,*y;
  1017. X{
  1018. X    register struct object *a,*b;
  1019. X
  1020. X    b = globcons(y,0);
  1021. X    a = loccons(x,b);
  1022. X    mfree(x);
  1023. X    mfree(y);
  1024. X    return(a);
  1025. X}
  1026. X
  1027. Xstruct object *length(x)        /* count */
  1028. Xregister struct object *x;
  1029. X{
  1030. X    register struct object *temp;
  1031. X    register char *cp;
  1032. X    register int i;
  1033. X
  1034. X    if (x==0) return(localize(objint((FIXNUM)0)));
  1035. X    if (cp = mkstring(x)) {
  1036. X        i = strlen(cp);
  1037. X        mfree(x);
  1038. X        return(localize(objint((FIXNUM)i)));
  1039. X    } else {
  1040. X        i = 0;
  1041. X        for (temp=x; temp; temp = temp->obcdr)
  1042. X            i++;
  1043. X        mfree(x);
  1044. X        return(localize(objint((FIXNUM)i)));
  1045. X    }
  1046. X}
  1047. X
  1048. Xlogois(x,y)        /* non-Logo is, despite the name */
  1049. Xregister struct object *x,*y;
  1050. X{
  1051. X    if (listp(x)) {
  1052. X        if (listp(y)) {
  1053. X            if (x==0) return(y==0);
  1054. X            if (y==0) return(0);
  1055. X            return(logois(x->obcar,y->obcar) &&
  1056. X                logois(x->obcdr,y->obcdr) );
  1057. X        }
  1058. X        return(0);
  1059. X    }
  1060. X    if (listp(y)) return(0);
  1061. X    if (x->obtype != y->obtype) return(0);
  1062. X    switch (x->obtype) {
  1063. X        case INT:
  1064. X            return(x->obint == y->obint);
  1065. X        case DUB:
  1066. X            return(x->obdub == y->obdub);
  1067. X        default:    /* case STRING */
  1068. X            return(!strcmp(x->obstr,y->obstr));
  1069. X    }
  1070. X}
  1071. X
  1072. Xstruct object *lis(x,y)
  1073. Xregister struct object *x,*y;
  1074. X{
  1075. X    register z;
  1076. X
  1077. X    z = logois(x,y);
  1078. X    mfree(x);
  1079. X    mfree(y);
  1080. X    return(z ? true() : false());
  1081. X}
  1082. X
  1083. Xleq(x,y)    /* non-Logo numeric equal */
  1084. Xregister struct object *x,*y;
  1085. X{
  1086. X    NUMBER dx,dy;
  1087. X    FIXNUM ix,iy;
  1088. X    int xint,yint;
  1089. X
  1090. X    if (listp(x) || listp(y)) return(logois(x,y));
  1091. X    if (stringp(x) && !nump(x)) return(logois(x,y));
  1092. X    if (stringp(y) && !nump(y)) return(logois(x,y));
  1093. X    xint = yint = 0;
  1094. X    if (stringp(x)) {
  1095. X        if (isint(x)) {
  1096. X            xint++;
  1097. X            sscanf(x->obstr,FIXFMT,&ix);
  1098. X        } else {
  1099. X            sscanf(x->obstr,EFMT,&dx);
  1100. X        }
  1101. X    } else {
  1102. X        if (intp(x)) {
  1103. X            xint++;
  1104. X            ix = x->obint;
  1105. X        } else {
  1106. X            dx = x->obdub;
  1107. X        }
  1108. X    }
  1109. X    if (stringp(y)) {
  1110. X        if (isint(y)) {
  1111. X            yint++;
  1112. X            sscanf(y->obstr,FIXFMT,&iy);
  1113. X        } else {
  1114. X            sscanf(y->obstr,EFMT,&dy);
  1115. X        }
  1116. X    } else {
  1117. X        if (intp(y)) {
  1118. X            yint++;
  1119. X            iy = y->obint;
  1120. X        } else {
  1121. X            dy = y->obdub;
  1122. X        }
  1123. X    }
  1124. X    if (xint != yint) {
  1125. X        if (xint) dx = ix;
  1126. X        else dy = iy;
  1127. X        xint = 0;
  1128. X    }
  1129. X    if (xint)
  1130. X        return (ix == iy);
  1131. X    else
  1132. X        return (dx == dy);
  1133. X}
  1134. X
  1135. Xstruct object *equal(x,y)    /* Logo equalp */
  1136. Xregister struct object *x,*y;
  1137. X{
  1138. X    register z;
  1139. X
  1140. X    z = leq(x,y);
  1141. X    mfree(x);
  1142. X    mfree(y);
  1143. X    return(z ? true() : false());
  1144. X}
  1145. X
  1146. Xstruct object *worcat(x,y)    /* word */
  1147. Xregister struct object *x,*y;
  1148. X{
  1149. X    char *val,*xp,*yp;
  1150. X    char xstr[30],ystr[30];
  1151. X
  1152. X    if (listp(x)) ungood("Word",x);
  1153. X    if (listp(y)) ungood("Word",y);
  1154. X    switch(x->obtype) {
  1155. X        case INT:
  1156. X            sprintf(xstr,FIXFMT,x->obint);
  1157. X            xp = xstr;
  1158. X            break;
  1159. X        case DUB:
  1160. X            sprintf(xstr,"%g",x->obdub);
  1161. X            if (!index(xstr,'.')) strcat(xstr,".0");
  1162. X            xp = xstr;
  1163. X            break;
  1164. X        default:    /* case STRING */
  1165. X            xp = x->obstr;
  1166. X    }
  1167. X    switch(y->obtype) {
  1168. X        case INT:
  1169. X            sprintf(ystr,FIXFMT,y->obint);
  1170. X            yp = ystr;
  1171. X            break;
  1172. X        case DUB:
  1173. X            sprintf(ystr,"%g",y->obdub);
  1174. X            if (!index(ystr,'.')) strcat(ystr,".0");
  1175. X            yp = ystr;
  1176. X            break;
  1177. X        default:    /* case STRING */
  1178. X            yp = y->obstr;
  1179. X    }
  1180. X    val=ckmalloc(strlen(xp)+strlen(yp)+1);
  1181. X    cpystr(val,xp,yp,NULL);
  1182. X    mfree(x);
  1183. X    mfree(y);
  1184. X    return(localize(objstr(val)));
  1185. X}
  1186. X
  1187. Xstruct object *sencat(x,y)    /* sentence */
  1188. Xstruct object *x,*y;
  1189. X{
  1190. X    register struct object *a,*b,*c;
  1191. X
  1192. X    if (x==0) {
  1193. X        if (listp(y)) return(y);
  1194. X        a = loccons(y,0);
  1195. X        mfree(y);
  1196. X        return(a);
  1197. X    }
  1198. X    if (listp(x)) {
  1199. X        c = a = globcons(0,0);
  1200. X        for (b=x; b->obcdr; b = b->obcdr) {
  1201. X            a->obcar = globcopy(b->obcar);
  1202. X            a->obcdr = globcopy(globcons(0,0));
  1203. X            a = a->obcdr;
  1204. X        }
  1205. X        a->obcar = globcopy(b->obcar);
  1206. X    }
  1207. X    else c = a = globcons(x,0);
  1208. X
  1209. X    if (listp(y)) b = y;
  1210. X    else b = globcons(y,0);
  1211. X
  1212. X    a->obcdr = globcopy(b);
  1213. X    mfree(x);
  1214. X    mfree(y);
  1215. X    return(localize(c));
  1216. X}
  1217. X
  1218. Xstruct object *memberp(thing,group)
  1219. Xstruct object *thing,*group;
  1220. X{
  1221. X    register char *cp;
  1222. X    register struct object *rest;
  1223. X    int i;
  1224. X
  1225. X    if (group==0) {
  1226. X        mfree(thing);
  1227. X        return(false());
  1228. X    }
  1229. X    if (cp = mkstring(group)) {
  1230. X        if (thing==0) {
  1231. X            mfree(group);
  1232. X            return(false());
  1233. X        }
  1234. X        switch (thing->obtype) {
  1235. X            case INT:
  1236. X                if((thing->obint >= 0)&&(thing->obint < 10)) {
  1237. X                    i = memb('0'+thing->obint,cp);
  1238. X                    break;
  1239. X                }
  1240. X            case CONS:
  1241. X            case DUB:
  1242. X                i = 0;
  1243. X                break;
  1244. X            default:    /* STRING */
  1245. X                if (strlen(thing->obstr) == 1) {
  1246. X                    i = memb(*(thing->obstr),cp);
  1247. X                } else i = 0;
  1248. X        }
  1249. X    } else {
  1250. X        i = 0;
  1251. X        for (rest=group; rest; rest=rest->obcdr) {
  1252. X            if (leq(rest->obcar,thing)) {
  1253. X                i++;
  1254. X                break;
  1255. X            }
  1256. X        }
  1257. X    }
  1258. X    mfree(thing);
  1259. X    mfree(group);
  1260. X    return(torf(i));
  1261. X}
  1262. X
  1263. Xstruct object *item(num,group)
  1264. Xstruct object *num,*group;
  1265. X{
  1266. X    int inum,ernum;
  1267. X    register char *cp;
  1268. X    register struct object *rest;
  1269. X    char str[2];
  1270. X
  1271. X    num = numconv(num,"Item");
  1272. X    if (intp(num)) inum = num->obint;
  1273. X    else inum = num->obdub;
  1274. X    if (inum <= 0) ungood("Item",num);
  1275. X    if (group == 0) ungood("Item",group);
  1276. X    if (cp = mkstring(group)) {
  1277. X        if (inum > strlen(cp)) {
  1278. X            pf1("%p has fewer than %d items.\n",group,inum);
  1279. X            errhand();
  1280. X        }
  1281. X        str[0] = cp[inum-1];
  1282. X        str[1] = '\0';
  1283. X        mfree(num);
  1284. X        mfree(group);
  1285. X        return(localize(objcpstr(str)));
  1286. X    } else {
  1287. X        ernum = inum;
  1288. X        for (rest = group; --inum; rest = rest->obcdr) {
  1289. X            if (rest==0) break;
  1290. X        }
  1291. X        if (rest==0) {
  1292. X            pf1("%p has fewer than %d items.\n",
  1293. X                    group,ernum);
  1294. X            errhand();
  1295. X        }
  1296. X        mfree(num);
  1297. X        rest = localize(rest->obcar);
  1298. X        mfree(group);
  1299. X        return(rest);
  1300. X    }
  1301. X}
  1302. X
  1303. END_OF_logoop.c
  1304. if test 10685 -ne `wc -c <logoop.c`; then
  1305.     echo shar: \"logoop.c\" unpacked with wrong size!
  1306. fi
  1307. # end of overwriting check
  1308. fi
  1309. if test -f logoproc.c -a "${1}" != "-c" ; then 
  1310.   echo shar: Will not over-write existing file \"logoproc.c\"
  1311. else
  1312. echo shar: Extracting \"logoproc.c\" \(11517 characters\)
  1313. sed "s/^X//" >logoproc.c <<'END_OF_logoproc.c'
  1314. X
  1315. X#include <stdio.h>
  1316. X#include "logo.h"
  1317. X
  1318. Xint errrec();
  1319. Xint ehand2();
  1320. Xint ehand3();
  1321. Xint leave();
  1322. X
  1323. Xextern char popname[];
  1324. Xextern int letflag, pflag, argno, yyline, rendflag, currtest;
  1325. Xextern int traceflag, *stkbase, stkbi, yychar, endflag, topf;
  1326. X#ifdef PAUSE
  1327. Xextern int pauselev, errpause, catching, flagquit;
  1328. X#endif
  1329. X#ifndef NOTURTLE
  1330. Xextern int turtdes;
  1331. X#endif
  1332. Xextern char charib, *getbpt, *ibufptr;
  1333. Xextern char titlebuf[];
  1334. Xextern struct lexstruct keywords[];
  1335. Xextern struct stkframe *fbr;
  1336. Xextern struct plist *proclist;
  1337. Xextern struct object *multarg;
  1338. Xextern struct runblock *thisrun;
  1339. X#ifndef YYSTYPE
  1340. X#define YYSTYPE int
  1341. X#endif
  1342. Xextern YYSTYPE yylval;
  1343. X
  1344. Xint doprep = 0;
  1345. Xint *newstk =NULL;
  1346. Xint newsti =0;
  1347. XFILE *pbuf =0;
  1348. Xstruct plist *pcell =NULL;
  1349. Xstruct alist *locptr =NULL, *newloc =NULL;
  1350. Xstruct object *allocstk[MAXALLOC] ={0};
  1351. X
  1352. Xint memb(ch,str)
  1353. Xregister char ch,*str;
  1354. X{
  1355. X    register char ch1;
  1356. X
  1357. X    while (ch1 = *str++)
  1358. X        if (ch == ch1) return(1);
  1359. X    return(0);
  1360. X}
  1361. X
  1362. Xchar *token(str)
  1363. Xregister char *str;
  1364. X{
  1365. X    static char output[NAMELEN+5];
  1366. X    register char ch,*op;
  1367. X
  1368. X    op = output;
  1369. X    while((op < &output[19]) && (ch = *str++) && !memb(ch," \t\"[\r\n:")){
  1370. X        if (ch >= 'A' && ch <= 'Z') ch += 'a'-'A';
  1371. X        *op++ = ch;
  1372. X    }
  1373. X    *op = '\0';
  1374. X    return(output);
  1375. X}
  1376. X
  1377. X#ifdef DEBUG
  1378. Xjfree(block)
  1379. Xchar *block;
  1380. X{
  1381. X    if (memtrace)
  1382. X        printf("Jfree loc=0%o\n",block);
  1383. X    if (block==0) printf("Trying to jfree zero.\n");
  1384. X    else free(block);
  1385. X}
  1386. X#endif
  1387. X
  1388. Xnewproc(nameob)
  1389. Xstruct object *nameob;
  1390. X{
  1391. X    register char *name;
  1392. X    register struct stkframe *stemp;
  1393. X    register struct lincell *ltemp;
  1394. X    struct plist *pptr;
  1395. X    int linlab;
  1396. X    int itemp;
  1397. X    char *temp,*tstr;
  1398. X    struct object *title;
  1399. X    char s[100];
  1400. X    int olp;
  1401. X    int oldlet;
  1402. X    int olc,c;
  1403. X    int pc;
  1404. X    extern struct plist *proclook();
  1405. X
  1406. X    name = nameob->obstr;
  1407. X    stemp=(struct stkframe *)ckzmalloc(sizeof(*stemp));
  1408. X    stemp->prevframe=fbr;
  1409. X    stemp->oldyyc= -2;
  1410. X    stemp->oldline= -1;
  1411. X    stemp->oldnewstk=newstk;
  1412. X    newstk = NULL;
  1413. X    stemp->oldnloc=newloc;
  1414. X    newloc=NULL;
  1415. X    stemp->argtord=argno;
  1416. X    stemp->prevpcell=pcell;
  1417. X    pcell = NULL;
  1418. X    stemp->loclist = NULL;
  1419. X    fbr=stemp;
  1420. X    doprep++;
  1421. X    argno=0;
  1422. X    if (pptr=proclook(name)) {
  1423. X        mfree(nameob);
  1424. X        newstk=pptr->realbase;
  1425. X        (pptr->recdepth)++;
  1426. X        title=pptr->ptitle;
  1427. X        pcell=pptr;
  1428. X    } else {
  1429. X        onintr(ehand2,&pbuf);
  1430. X        cpystr (s,name,EXTEN,NULL);
  1431. X        if (!(pbuf=fopen(s,"r"))) {
  1432. X            extern int errno;
  1433. X
  1434. X            if (errno != 2) /* ENOENT */ {
  1435. X                onintr(errrec,1);
  1436. X#ifdef SMALL
  1437. X                printf("%s: error %d\n",s,errno);
  1438. X#else
  1439. X                perror(s);
  1440. X#endif
  1441. X                errhand();
  1442. X            }
  1443. X            cpystr(s,LIBLOGO,name,EXTEN,NULL);
  1444. X            if (!(pbuf = fopen(s,"r"))) {
  1445. X                onintr(errrec,1);
  1446. X                printf("You haven't told me how to %s.\n",name);
  1447. X                errhand();
  1448. X            }
  1449. X        }
  1450. X        pptr=(struct plist *)ckzmalloc(sizeof(*pptr));
  1451. X        pptr->plines=NULL;
  1452. X        pptr->procname=globcopy(nameob);
  1453. X        mfree(nameob);
  1454. X        temp=s;
  1455. X        while ( ((c=getc(pbuf)) != EOF) && (c!='\n') ) *temp++=c;
  1456. X        if (c==EOF) {
  1457. X            printf("Bad format in %s title line.\n",
  1458. X                pptr->procname->obstr);
  1459. X            errhand();
  1460. X        }
  1461. X        *temp++='\n';
  1462. X        *temp='\0';
  1463. X        title=globcopy(objcpstr(s));
  1464. X        pptr->after=proclist;
  1465. X        pptr->recdepth=1;
  1466. X        pptr->ptitle=title;
  1467. X        pptr->before=NULL;
  1468. X        if (proclist) proclist->before = pptr;
  1469. X        proclist=pptr;
  1470. X        pcell=pptr;
  1471. X    }
  1472. X    tstr = title->obstr;
  1473. Xnextarg: while((c= *tstr++)!=':' && c!='\n')
  1474. X        ;
  1475. X    if (c==':') {
  1476. X        temp=s;
  1477. X        while ((c= *tstr++)!=' ' && c!='\n') *temp++=c;
  1478. X        *temp='\0';
  1479. X        tstr--;
  1480. X        loccreate(globcopy(objcpstr(s)),&newloc);
  1481. X        argno++;
  1482. X        goto nextarg;
  1483. X    }
  1484. X    if (pptr->recdepth!=1) return;
  1485. X    olp=pflag;
  1486. X    pflag=1;
  1487. X    oldlet=letflag;
  1488. X    letflag=0;
  1489. X    olc=charib;
  1490. X    charib=0;
  1491. X    newstk=(int *)ckmalloc(PSTKSIZ*sizeof(int));
  1492. X    *newstk=0;
  1493. X    newsti=1;
  1494. X    *(newstk+newsti) = -1;    /* BH 6/25/82 in case yylex blows up */
  1495. X    itemp = '\n';
  1496. X    while ((pc = yylex()) != -1) {
  1497. X        if (pc==1) return;
  1498. X        if ((itemp == '\n') && isuint(pc)) {
  1499. X            linlab=((struct object *)yylval)->obint;
  1500. X            ltemp=(struct lincell *)ckmalloc(sizeof(*ltemp));
  1501. X            ltemp->linenum=linlab;
  1502. X            ltemp->base=newstk;
  1503. X            ltemp->index=newsti;
  1504. X            ltemp->nextline=pptr->plines;
  1505. X            pptr->plines=ltemp;
  1506. X        }
  1507. X        *(newstk+newsti++)=pc;
  1508. X        if (newsti==PSTKSIZ-1) newfr();
  1509. X        *(newstk+newsti++)=yylval;
  1510. X        if (isstored(pc)) {
  1511. X            yylval = (YYSTYPE)globcopy(yylval);
  1512. X            mfree(yylval);
  1513. X        }
  1514. X        if (newsti==PSTKSIZ-1) newfr();
  1515. X        *(newstk+newsti) = -1;
  1516. X        itemp = pc;
  1517. X    }
  1518. X    *(newstk+newsti)= -1;
  1519. X    *(newstk+PSTKSIZ-1)=0;
  1520. X    pflag=olp;
  1521. X    letflag=oldlet;
  1522. X    charib=olc;
  1523. X    fclose(pbuf);
  1524. X    onintr(errrec,1);
  1525. X    while (*newstk!=0) newstk= (int *)*newstk;
  1526. X    pptr->realbase=newstk;
  1527. X}
  1528. X
  1529. Xprocprep()
  1530. X{
  1531. X    doprep=0;
  1532. X    fbr->oldline=yyline;
  1533. X    fbr->oldbpt=getbpt;
  1534. X    getbpt=0;
  1535. X    fbr->loclist=locptr;
  1536. X    locptr=newloc;
  1537. X    newloc=NULL;
  1538. X    fbr->stk=stkbase;
  1539. X    stkbase=newstk;
  1540. X    newstk=NULL;
  1541. X    fbr->ind=stkbi;
  1542. X    stkbi=1;
  1543. X    newsti=0;
  1544. X    argno= -1;
  1545. X    fbr->oldpfg = pflag;
  1546. X    pflag=2;
  1547. X    fbr->iftest = currtest;
  1548. X    if (traceflag) intrace();
  1549. X}
  1550. X
  1551. Xfrmpop(val)
  1552. Xregister struct object *val;
  1553. X{
  1554. X    struct alist *atemp0,*atemp1,*atemp2;
  1555. X    register struct stkframe *ftemp;
  1556. X    struct lincell *ltemp,*ltemp2;
  1557. X    register i;
  1558. X    int *stemp;
  1559. X    int stval;
  1560. X
  1561. X    if (traceflag) outtrace(val);
  1562. X    if (!pcell) goto nopcell;
  1563. X    strcpy(popname,pcell->procname->obstr);
  1564. X    (pcell->recdepth)--;
  1565. X    if (pcell->recdepth==0) {
  1566. X        lfree(pcell->procname);
  1567. X        lfree(pcell->ptitle);
  1568. X        if (pcell->before) (pcell->before)->after=pcell->after;
  1569. X        else proclist=pcell->after;
  1570. X        if (pcell->after) (pcell->after)->before=pcell->before;
  1571. X        for(ltemp=pcell->plines;ltemp;ltemp=ltemp2) {
  1572. X            ltemp2=ltemp->nextline;
  1573. X            JFREE(ltemp);
  1574. X        }
  1575. X        if ((stemp=stkbase) == 0) goto nostack;
  1576. X        while (*stemp!=0) stemp= (int *)*stemp;
  1577. X        for (i=1;;i++) {
  1578. X            stval= *(stemp+i);
  1579. X            if (isstored(stval))
  1580. X            {
  1581. X                if (i==PSTKSIZ-2) {
  1582. X                    stkbase= (int *)*(stemp+PSTKSIZ-1);
  1583. X                    JFREE(stemp);
  1584. X                    stemp=stkbase;
  1585. X                    i=0;
  1586. X                }
  1587. X                lfree(*(stemp+ (++i)));
  1588. X            } else if (stval== -1) {
  1589. X                JFREE(stemp);
  1590. X                break;
  1591. X            } else {
  1592. X                if (i==PSTKSIZ-2) {
  1593. X                    stkbase= (int *)*(stemp+PSTKSIZ-1);
  1594. X                    JFREE(stemp);
  1595. X                    stemp=stkbase;
  1596. X                    i=1;
  1597. X                } else i++;
  1598. X            }
  1599. X            if (i==PSTKSIZ-2) {
  1600. X                stkbase= (int *)*(stemp+PSTKSIZ-1);
  1601. X                JFREE(stemp);
  1602. X                stemp=stkbase;
  1603. X                i=0;
  1604. X            }
  1605. X        }
  1606. X    nostack:
  1607. X        JFREE(pcell);
  1608. X    }
  1609. Xnopcell:
  1610. X    ftemp=fbr;
  1611. X    stkbase=ftemp->stk;
  1612. X    stkbi=ftemp->ind;
  1613. X    newstk=ftemp->oldnewstk;
  1614. X    atemp0=newloc;    /* BH 6/20/82 maybe never did procprep */
  1615. X    newloc=ftemp->oldnloc;
  1616. X    pflag = fbr->oldpfg;
  1617. X    atemp1=locptr;
  1618. X    locptr=ftemp->loclist;
  1619. X    argno=ftemp->argtord;
  1620. X    pcell=ftemp->prevpcell;
  1621. X    yychar=ftemp->oldyyc;
  1622. X    yylval=ftemp->oldyyl;
  1623. X    yyline=ftemp->oldline;
  1624. X    getbpt=ftemp->oldbpt;
  1625. X    currtest=ftemp->iftest;
  1626. X    fbr=ftemp->prevframe;
  1627. X    JFREE(ftemp);
  1628. X    while (atemp1) {
  1629. X        atemp2=atemp1->next;
  1630. X        if (atemp1->name) lfree(atemp1->name);
  1631. X        if (atemp1->val!=(struct object *)-1)    /* BH 2/28/80 was NULL instead of -1 */
  1632. X            lfree(atemp1->val);
  1633. X        JFREE(atemp1);
  1634. X        atemp1=atemp2;
  1635. X    }
  1636. X    while (atemp0) {
  1637. X        atemp2=atemp0->next;
  1638. X        if (atemp0->name) lfree(atemp0->name);
  1639. X        if (atemp0->val!=(struct object *)-1)
  1640. X            lfree(atemp0->val);
  1641. X        JFREE(atemp0);
  1642. X        atemp0=atemp2;
  1643. X    }
  1644. X}
  1645. X
  1646. Xproccreate(nameob)
  1647. Xregister struct object *nameob;
  1648. X{
  1649. X    register char *name;
  1650. X    char temp[16];
  1651. X    register FILDES edfd;
  1652. X    int pid;
  1653. X
  1654. X#ifndef NOTURTLE
  1655. X    if (turtdes<0) textscreen();
  1656. X#endif
  1657. X    name = token(nameob->obstr);
  1658. X    if (strlen(name)>NAMELEN) {
  1659. X        pf1("Procedure name must be no more than %d letters.",NAMELEN);
  1660. X        errhand();
  1661. X    }
  1662. X    cpystr(temp,name,EXTEN,NULL);
  1663. X    if ((edfd=open(temp,READ,0))>=0) {
  1664. X        close(edfd);
  1665. X        nputs(name);
  1666. X        puts(" is already defined.");
  1667. X        errhand();
  1668. X    }
  1669. X    if ((edfd = creat(temp,0666)) < 0) {
  1670. X        printf("Can't write %s.\n",name);
  1671. X        errhand();
  1672. X    }
  1673. X    onintr(ehand3,edfd);
  1674. X    mfree(nameob);
  1675. X    write(edfd,titlebuf,strlen(titlebuf));
  1676. X    addlines(edfd);
  1677. X    onintr(errrec,1);
  1678. X}
  1679. X
  1680. Xhelp()
  1681. X{
  1682. X    FILE *sbuf;
  1683. X
  1684. X    sbuf=fopen(HELPFILE,"r");
  1685. X    if (sbuf == NULL) {
  1686. X        printf("? Help file missing, sorry.\n");
  1687. X        return;
  1688. X    }
  1689. X    onintr(ehand2,sbuf);
  1690. X    while(putch(getc(sbuf))!=EOF)
  1691. X        ;
  1692. X    fclose(sbuf);
  1693. X    onintr(errrec,1);
  1694. X}
  1695. X
  1696. Xstruct object *describe(arg)
  1697. Xstruct object *arg;
  1698. X{
  1699. X    register char *argstr;
  1700. X    register struct lexstruct *lexp;
  1701. X    FILE *sbuf;
  1702. X    char fname[30];
  1703. X
  1704. X    if (!stringp(arg)) ungood("Describe",arg);
  1705. X    argstr = token(arg->obstr);
  1706. X    for (lexp = keywords; lexp->word; lexp++)
  1707. X         if (!strcmp(argstr,lexp->word) || 
  1708. X             (lexp->abbr && !strcmp(argstr,lexp->abbr)))
  1709. X            break;
  1710. X    if (!lexp->word) {
  1711. X        pf1("%p isn't a primitive.\n",arg);
  1712. X        errhand();
  1713. X    }
  1714. X    if (strlen(lexp->word) > 9)    /* kludge for Eunice */
  1715. X        cpystr(fname,DOCLOGO,lexp->abbr,NULL);
  1716. X    else
  1717. X        cpystr(fname,DOCLOGO,lexp->word,NULL);
  1718. X    if (!(sbuf=fopen(fname,"r"))) {
  1719. X        printf("Sorry, I have no information about %s\n",lexp->word);
  1720. X        errhand();
  1721. X    } else {
  1722. X        onintr(ehand2,sbuf);
  1723. X        while (putch(getc(sbuf))!=EOF)
  1724. X            ;
  1725. X        fclose(sbuf);
  1726. X    }
  1727. X    onintr(errrec,1);
  1728. X    mfree(arg);
  1729. X    return ((struct object *)(-1));
  1730. X}
  1731. X
  1732. Xerrwhere()
  1733. X{
  1734. X    register i =0;
  1735. X    register struct object **astk;
  1736. X    register struct plist *opc;
  1737. X
  1738. X    cboff();    /* BH 12/13/81 */
  1739. X    ibufptr=NULL;
  1740. X    if (doprep) {
  1741. X        procprep();
  1742. X        frmpop(-1);
  1743. X    }
  1744. X
  1745. X    for (astk=allocstk;i<MAXALLOC;i++)
  1746. X        if (astk[i]!=0)
  1747. X            mfree(astk[i]);
  1748. X
  1749. X    if (multarg) {
  1750. X        lfree(multarg);
  1751. X        multarg = 0;
  1752. X    }    /* BH 10/31/81 multarg isn't on astk, isn't mfreed. */
  1753. X
  1754. X#ifdef PAUSE
  1755. X    if ((errpause||pauselev) && fbr && !topf) {
  1756. X        /* I hope this pauses on error */
  1757. X        if (!pflag && !getbpt) charib=0;
  1758. X        dopause();
  1759. X    }
  1760. X    else
  1761. X#endif
  1762. X    {
  1763. X        opc = pcell;
  1764. X        if (fbr && fbr->oldline==-1) {
  1765. X            opc=fbr->prevpcell;
  1766. X        }
  1767. X        if (opc&&!topf)
  1768. X            printf("You were at line %d in procedure %s\n",
  1769. X                yyline,opc->procname->obstr);
  1770. X    }
  1771. X}
  1772. X
  1773. Xerrzap() {
  1774. X    while (thisrun)
  1775. X        unrun();
  1776. X
  1777. X    while (fbr)
  1778. X        frmpop(-1);
  1779. X
  1780. X    charib=0;
  1781. X    if(traceflag)traceflag=1;
  1782. X    topf=0;
  1783. X    yyline=0;
  1784. X    letflag=0;
  1785. X    pflag=0;
  1786. X    endflag=0;
  1787. X    rendflag=0;
  1788. X    argno= -1;
  1789. X    newstk=NULL;
  1790. X    newsti=0;
  1791. X    stkbase=NULL;
  1792. X    stkbi=0;
  1793. X    fbr=NULL;
  1794. X    locptr=NULL;
  1795. X    newloc=NULL;
  1796. X    proclist=NULL;
  1797. X    pcell=NULL;
  1798. X#ifdef PAUSE
  1799. X    pauselev = 0;
  1800. X#endif
  1801. X}
  1802. X
  1803. Xerrrec()
  1804. X{
  1805. X    /* Here on SIGQUIT */
  1806. X#ifdef PAUSE
  1807. X    if (catching)
  1808. X#endif
  1809. X        errhand();
  1810. X#ifdef PAUSE
  1811. X    flagquit++;    /* We'll catch this later */
  1812. X#endif
  1813. X}
  1814. X
  1815. Xehand2(fle)
  1816. Xregister FILE *fle;
  1817. X{
  1818. X    fclose(fle);
  1819. X    errhand();
  1820. X}
  1821. X
  1822. Xehand3(fle)
  1823. Xregister FILDES fle;
  1824. X{
  1825. X    close(fle);
  1826. X    errhand();
  1827. X}
  1828. X
  1829. Xstruct object *tracefuns = 0;
  1830. X
  1831. Xltrace() {    /* trace everything */
  1832. X    lfree(tracefuns);
  1833. X    tracefuns = (struct object *)0;
  1834. X    traceflag = 1;
  1835. X}
  1836. X
  1837. Xluntrace() {    /* trace nothing */
  1838. X    lfree(tracefuns);
  1839. X    tracefuns = (struct object *)0;
  1840. X    traceflag = 0;
  1841. X}
  1842. X
  1843. Xstruct object *sometrace(funs)
  1844. Xstruct object *funs;
  1845. X{
  1846. X    if (funs==0) {
  1847. X        luntrace();
  1848. X    } else if (!listp(funs)) {
  1849. X        ungood("Trace",funs);
  1850. X    } else {
  1851. X        tracefuns = globcopy(funs);
  1852. X        mfree(funs);
  1853. X        traceflag = 1;
  1854. X    }
  1855. X    return ((struct object *)(-1));
  1856. X}
  1857. X
  1858. Xint chktrace(procname)
  1859. Xchar *procname;
  1860. X{
  1861. X    struct object *rest;
  1862. X
  1863. X    if (tracefuns == 0) return(1);
  1864. X    for (rest=tracefuns; rest; rest=rest->obcdr) {
  1865. X        if (!stringp(rest->obcar)) continue;
  1866. X        if (!strcmp(token(rest->obcar->obstr),procname)) return(1);
  1867. X    }
  1868. X    return(0);
  1869. X}
  1870. X
  1871. Xintrace()
  1872. X{
  1873. X    register struct alist *aptr;
  1874. X
  1875. X    if (!pcell) return;
  1876. X    if (!chktrace(pcell->procname->obstr)) return;
  1877. X    indent(traceflag-1);
  1878. X    nputs(pcell->procname->obstr);
  1879. X    if (locptr && (locptr->val != (struct object *)-1)) {
  1880. X        pf1(" of %l",locptr->val);    /* BH locptr->val was inval */
  1881. X        for (aptr=locptr->next;aptr;aptr=aptr->next) {
  1882. X            if (aptr->val == (struct object *)-1) break;
  1883. X            pf1(" and %l",aptr->val);    /* was inval */
  1884. X        }
  1885. X        putchar('\n');
  1886. X    }
  1887. X    else puts(" called.");
  1888. X    fflush(stdout);
  1889. X    traceflag++;
  1890. X}
  1891. X
  1892. Xouttrace(retval)
  1893. Xregister struct object *retval;
  1894. X{
  1895. X    if (!pcell) return;
  1896. X    if (!chktrace(pcell->procname->obstr)) return;
  1897. X    if (traceflag>1) traceflag--;
  1898. X    indent(traceflag-1);
  1899. X    nputs(pcell->procname->obstr);
  1900. X    if (retval != (struct object *)-1) pf1(" outputs %l\n",retval);
  1901. X    else puts(" stops.");
  1902. X    fflush(stdout);
  1903. X}
  1904. X
  1905. Xindent(no)
  1906. Xregister int no;
  1907. X{
  1908. X    while (no--)putchar(' ');
  1909. X}
  1910. X
  1911. END_OF_logoproc.c
  1912. if test 11517 -ne `wc -c <logoproc.c`; then
  1913.     echo shar: \"logoproc.c\" unpacked with wrong size!
  1914. fi
  1915. # end of overwriting check
  1916. fi
  1917. if test -f turtle.c -a "${1}" != "-c" ; then 
  1918.   echo shar: Will not over-write existing file \"turtle.c\"
  1919. else
  1920. echo shar: Extracting \"turtle.c\" \(9873 characters\)
  1921. sed "s/^X//" >turtle.c <<'END_OF_turtle.c'
  1922. X
  1923. X#include "logo.h"
  1924. X
  1925. X#ifndef NOTURTLE
  1926. X
  1927. X#include <math.h>
  1928. X
  1929. Xextern char *getenv();
  1930. Xint turtdes; /* file descriptor for open turtle */
  1931. Xint color;    /* pen color */
  1932. Xint pendown = 0; /* nonzero with pen down */
  1933. Xint penerase = 0; /* 0=pd, 1=pe, 2=px, pendown must be nonzero */
  1934. Xint shown = 1;    /* nonzero if turtle is visible */
  1935. Xint textmode = 0;    /* not turtle off */
  1936. XNUMBER yscrunch;    /* scale factor for y */
  1937. Xstruct display *mydpy;
  1938. X
  1939. X#ifdef ATARI
  1940. X#include "atari.i"
  1941. X#endif
  1942. X
  1943. X#ifdef GIGI
  1944. X#include "gigi.i"
  1945. X#endif
  1946. X
  1947. X#ifdef ADM
  1948. X#include "admtek.i"
  1949. X#include "adm.i"
  1950. X#endif
  1951. X
  1952. X#ifdef TEK
  1953. X#ifndef ADM
  1954. X#include "admtek.i"
  1955. X#endif
  1956. X#include "tek.i"
  1957. X#endif
  1958. X
  1959. X#ifdef SUN
  1960. X#include "sun.i"
  1961. X#endif
  1962. X
  1963. XNUMBER ncheck(arg)
  1964. Xstruct object *arg;
  1965. X{
  1966. X    NUMBER val;
  1967. X
  1968. X    arg = numconv(arg,"Turtle command");
  1969. X    arg = dubconv(arg);
  1970. X    val = arg->obdub;
  1971. X    mfree(arg);
  1972. X    return(val);
  1973. X}
  1974. X
  1975. Xdpyinit() {
  1976. X    char *ttytype;
  1977. X
  1978. X    ttytype = getenv("TERM");
  1979. X#ifdef GIGI
  1980. X    if (!strcmp(ttytype,"gigi"))
  1981. X        mydpy = &gigi;
  1982. X    else
  1983. X#endif
  1984. X#ifdef ATARI
  1985. X    if (!strcmp(ttytype,"atari"))
  1986. X        mydpy = &bwatari;
  1987. X    else
  1988. X#endif
  1989. X#ifdef ADM
  1990. X    if (!strncmp(ttytype,"adm",3))
  1991. X        mydpy = &adm;
  1992. X    else
  1993. X#endif
  1994. X#ifdef TEK
  1995. X    if (!strncmp(ttytype,"tek",3))
  1996. X        mydpy = &tek;
  1997. X    else
  1998. X#endif
  1999. X#ifdef SUN
  2000. X    if (1 || !strcmp(ttytype,"sun"))    /* Sun is always a sun */
  2001. X        mydpy = &sun;
  2002. X    else
  2003. X#endif
  2004. X    {
  2005. X        printf("I don't recognize your terminal type!\n");
  2006. X        errhand();
  2007. X    }
  2008. X    pendown = 1; penerase = 0; shown = 1;
  2009. X    textmode = 0;
  2010. X    mydpy->turtx = mydpy->turty = mydpy->turth = 0.0;
  2011. X    printf(mydpy->init);
  2012. X    if (!(mydpy->cleared)) {
  2013. X        printf(mydpy->clear);
  2014. X        (*mydpy->state)('c');
  2015. X        mydpy->cleared++;
  2016. X        yscrunch = mydpy->stdscrunch;
  2017. X    }
  2018. X    turtdes = -1;
  2019. X    (*mydpy->infn)();
  2020. X    (*mydpy->drawturt)(0);
  2021. X}
  2022. X
  2023. Xstruct object *getturtle(arg)
  2024. Xregister struct object *arg;
  2025. X{
  2026. X    int lsflag[2];    /* BH 1/4/81 */
  2027. X    register char *temp,*argc;
  2028. X    char c[100];
  2029. X    char astr[20];
  2030. X
  2031. X    if (stringp(arg)) argc = arg->obstr;
  2032. X    else argc = "";
  2033. X    if (!strcmp(argc,"off")) {
  2034. X#ifdef FLOOR
  2035. X        if (turtdes>0) {
  2036. X            close (turtdes);
  2037. X            printf("Please\007 unplug the turtle\007 and put it\007 away!\n");
  2038. X        }
  2039. X#endif /* FLOOR */
  2040. X        if (turtdes<0) {
  2041. X            printf(mydpy->finish);
  2042. X            (*mydpy->outfn)();
  2043. X        }
  2044. X        turtdes = 0;
  2045. X        mfree(arg);
  2046. X        return((struct object *)(-1));
  2047. X    }
  2048. X    if (!strcmp(argc,"dpy")||!strcmp(argc,"display")) {
  2049. X
  2050. X#ifdef FLOOR
  2051. X        if (turtdes>0) {
  2052. X            close (turtdes);
  2053. X            printf("Please\007 unplug the turtle\007 and put it\007 away!\n");
  2054. X        }
  2055. X#endif /* FLOOR */
  2056. X
  2057. X        dpyinit();
  2058. X        mfree(arg);
  2059. X        return ((struct object *)(-1));
  2060. X    }
  2061. X#ifdef FLOOR
  2062. X    if (intp(arg)) {
  2063. X        sprintf(astr,FIXFMT,arg->obint);
  2064. X        argc = astr;
  2065. X    }
  2066. X    temp = c;
  2067. X    cpystr(temp,"/dev/turtle",argc,NULL);
  2068. X    if (turtdes>0) close(turtdes);
  2069. X    if((turtdes = open(c,2)) < 0) {
  2070. X        turtdes = 0;
  2071. X        pf1("Turtle %l not available.\n",arg);
  2072. X    } else printf("Please put the turtle away when you're done!\n");
  2073. X    mfree(arg);
  2074. X    return ((struct object *)(-1));
  2075. X#else
  2076. X    ungood("Turtle",arg);
  2077. X#endif /* FLOOR */
  2078. X}
  2079. X
  2080. Xdpysxy(newx,newy)
  2081. XNUMBER newx,newy;
  2082. X{
  2083. X    if ((newx < mydpy->xlow) || (newx > mydpy->xhigh) ||
  2084. X        (newy < mydpy->ylow) || (newy > mydpy->yhigh)) {
  2085. X            puts("Out of bounds!");
  2086. X            errhand();
  2087. X    }
  2088. X    if (shown) (*mydpy->drawturt)(1);
  2089. X    if (fabs(newx) < 0.01) newx = 0.0;
  2090. X    if (fabs(newy) < 0.01) newy = 0.0;
  2091. X    if (pendown)
  2092. X        (*mydpy->drawfrom)(mydpy->turtx,yscrunch*mydpy->turty);
  2093. X    mydpy->turtx = newx;
  2094. X    mydpy->turty = newy;
  2095. X    if (pendown)
  2096. X        (*mydpy->drawto)(newx,yscrunch*newy);
  2097. X    (*mydpy->state)('G');
  2098. X    if (shown) (*mydpy->drawturt)(0);
  2099. X}
  2100. X
  2101. Xdpyforw(dist)
  2102. XNUMBER dist;
  2103. X{
  2104. X    NUMBER newx,newy,deltax,deltay;
  2105. X
  2106. X    tcheck();
  2107. X    (*mydpy->txtchk)();
  2108. X    deltax = dist * sin((mydpy->turth)*3.141592654/180.0);
  2109. X    if (fabs(deltax) < 1.0e-5) deltax = 0.0;
  2110. X    deltay = dist * cos((mydpy->turth)*3.141592654/180.0);
  2111. X    if (fabs(deltay) < 1.0e-5) deltay = 0.0;
  2112. X    newx = mydpy->turtx + deltax;
  2113. X    newy = mydpy->turty + deltay;
  2114. X    dpysxy(newx,newy);
  2115. X}
  2116. X
  2117. Xstruct object *forward(arg)
  2118. Xregister struct object *arg;
  2119. X{
  2120. X    NUMBER dist;
  2121. X
  2122. X    dist = ncheck(arg);
  2123. X#ifdef FLOOR
  2124. X    if (turtdes > 0) {
  2125. X        if (dist < 0.0)
  2126. X            moveturtle('b',-6*(int)dist);
  2127. X        else
  2128. X            moveturtle('f',6*(int)dist);
  2129. X        return ((struct object *)(-1));
  2130. X    }
  2131. X#endif /* FLOOR */
  2132. X    dpyforw(dist);
  2133. X    return ((struct object *)(-1));
  2134. X}
  2135. X
  2136. Xstruct object *back(arg)
  2137. Xregister struct object *arg;
  2138. X{
  2139. X    NUMBER dist;
  2140. X
  2141. X    dist = ncheck(arg);
  2142. X#ifdef FLOOR
  2143. X    if (turtdes > 0) {
  2144. X        if (dist < 0.0)
  2145. X            moveturtle('f',-6*(int)dist);
  2146. X        else
  2147. X            moveturtle('b',6*(int)dist);
  2148. X        return ((struct object *)(-1));
  2149. X    }
  2150. X#endif /* FLOOR */
  2151. X    dpyforw(-dist);
  2152. X    return ((struct object *)(-1));
  2153. X}
  2154. X
  2155. Xdpysh(angle)
  2156. XNUMBER angle;
  2157. X{
  2158. X    (*mydpy->txtchk)();
  2159. X    if (shown) (*mydpy->drawturt)(1);
  2160. X    mydpy->turth = angle;
  2161. X    while (mydpy->turth+11.0 < 0.0) mydpy->turth += 360.0;
  2162. X    while (mydpy->turth+11.0 >= 360.0) mydpy->turth -= 360.0;
  2163. X    if (shown) (*mydpy->drawturt)(0);
  2164. X    (*mydpy->turnturt)();
  2165. X}
  2166. X
  2167. Xdpyturn(angle)
  2168. XNUMBER angle;
  2169. X{
  2170. X    tcheck();
  2171. X    dpysh(mydpy->turth + angle);
  2172. X}
  2173. X
  2174. Xstruct object *left(arg)
  2175. Xregister struct object *arg;
  2176. X{
  2177. X    NUMBER dist;
  2178. X
  2179. X    dist = ncheck(arg);
  2180. X#ifdef FLOOR
  2181. X    if (turtdes > 0) {
  2182. X        if (dist < 0.0)
  2183. X            moveturtle('r',(-2*(int)dist)/5);
  2184. X        else
  2185. X            moveturtle('l',(2*(int)dist)/5);
  2186. X        return ((struct object *)(-1));
  2187. X    }
  2188. X#endif /* FLOOR */
  2189. X    dpyturn(-dist);
  2190. X    return ((struct object *)(-1));
  2191. X}
  2192. X
  2193. Xstruct object *right(arg)
  2194. Xregister struct object *arg;
  2195. X{
  2196. X    NUMBER dist;
  2197. X
  2198. X    dist = ncheck(arg);
  2199. X#ifdef FLOOR
  2200. X    if (turtdes > 0) {
  2201. X        if (dist < 0.0)
  2202. X            moveturtle('l',(-2*(int)dist)/5);
  2203. X        else
  2204. X            moveturtle('r',(2*(int)dist)/5);
  2205. X        return ((struct object *)(-1));
  2206. X    }
  2207. X#endif /* FLOOR */
  2208. X    dpyturn(dist);
  2209. X    return ((struct object *)(-1));
  2210. X}
  2211. X
  2212. X#ifdef FLOOR
  2213. Xfcheck() {
  2214. X    if (turtdes <= 0) {
  2215. X        puts("You don't have a floor turtle!");
  2216. X        errhand();
  2217. X    }
  2218. X}
  2219. X
  2220. Xstruct object *hitoot(arg)
  2221. Xregister struct object *arg;
  2222. X{
  2223. X    NUMBER dist;
  2224. X
  2225. X    fcheck();
  2226. X    dist = ncheck(arg);
  2227. X    moveturtle('H',(15*(int)dist)/2);
  2228. X    return ((struct object *)(-1));
  2229. X}
  2230. X
  2231. Xstruct object *lotoot(arg)
  2232. Xregister struct object *arg;
  2233. X{
  2234. X    NUMBER dist;
  2235. X
  2236. X    fcheck();
  2237. X    dist = ncheck(arg);
  2238. X    moveturtle('L',(15*(int)dist)/2);
  2239. X    return ((struct object *)(-1));
  2240. X}
  2241. X
  2242. Xmoveturtle(where,arg)
  2243. Xregister int arg;
  2244. X{
  2245. X    char buff[2];
  2246. X
  2247. X    buff[0] = where;
  2248. X    while (arg >= 0400) {
  2249. X        buff[1] = 0377;
  2250. X        write(turtdes,buff,2);
  2251. X        arg -= 0377;
  2252. X    }
  2253. X    buff[1] = arg;
  2254. X    write(turtdes,buff,2);
  2255. X}
  2256. X
  2257. Xlampon() {
  2258. X    int i;
  2259. X
  2260. X    fcheck();
  2261. X    i = 'B';
  2262. X    write(turtdes,&i,2);
  2263. X}
  2264. X
  2265. Xlampoff() {
  2266. X    int i;
  2267. X
  2268. X    fcheck();
  2269. X    i = 'B'+0400;
  2270. X    write(turtdes,&i,2);
  2271. X}
  2272. X
  2273. Xstruct object *touchsense(which)
  2274. X{
  2275. X    char x;
  2276. X
  2277. X    fcheck();
  2278. X    read (turtdes,&x,1);
  2279. X    if ( (0200>>which) & x) return (true());
  2280. X    else return (false());
  2281. X}
  2282. X
  2283. Xstruct object *ftouch() {
  2284. X    return(touchsense(0));
  2285. X}
  2286. X
  2287. Xstruct object *btouch() {
  2288. X    return(touchsense(1));
  2289. X}
  2290. X
  2291. Xstruct object *ltouch() {
  2292. X    return(touchsense(2));
  2293. X}
  2294. X
  2295. Xstruct object *rtouch() {
  2296. X    return(touchsense(3));
  2297. X}
  2298. X#endif
  2299. X
  2300. Xint tcheck() {
  2301. X    if (turtdes > 0) {
  2302. X        puts("You don't have a display turtle!");
  2303. X        errhand();
  2304. X    }
  2305. X    if (turtdes == 0) dpyinit();    /* free turtle "display */
  2306. X}
  2307. X
  2308. XNUMBER posangle(angle)
  2309. XNUMBER angle;
  2310. X{
  2311. X    if (angle < 0.0) return(angle+360.0);
  2312. X    return(angle);
  2313. X}
  2314. X
  2315. Xstruct object *pencolor(pen)
  2316. Xstruct object *pen;
  2317. X{
  2318. X    NUMBER dpen;
  2319. X
  2320. X    tcheck();
  2321. X    (*mydpy->txtchk)();
  2322. X    dpen = ncheck(pen);
  2323. X    (*mydpy->penc)((int)dpen);
  2324. X    color = dpen;
  2325. X    return ((struct object *)(-1));
  2326. X}
  2327. X
  2328. Xint setcolor(pen,colorlist)
  2329. Xstruct object *pen,*colorlist;
  2330. X{
  2331. X    NUMBER number;
  2332. X    register int ipen;
  2333. X
  2334. X    tcheck();
  2335. X    (*mydpy->txtchk)();
  2336. X    number = ncheck(pen);
  2337. X    ipen = number;
  2338. X    (*mydpy->setc)(ipen,colorlist);
  2339. X}
  2340. X
  2341. Xint setxy(strx,stry)
  2342. Xstruct object *strx,*stry;
  2343. X{
  2344. X    NUMBER x,y;
  2345. X
  2346. X    tcheck();
  2347. X    (*mydpy->txtchk)();
  2348. X    x = ncheck(strx);
  2349. X    y = ncheck(stry);
  2350. X    dpysxy(x,y);
  2351. X}
  2352. X
  2353. Xstruct object *setheading(arg)
  2354. Xstruct object *arg;
  2355. X{
  2356. X    NUMBER heading;
  2357. X
  2358. X    tcheck();
  2359. X    (*mydpy->txtchk)();
  2360. X    heading = ncheck(arg);
  2361. X    dpysh(heading);
  2362. X    return ((struct object *)(-1));
  2363. X}
  2364. X
  2365. Xstruct object *xcor()
  2366. X{
  2367. X    tcheck();
  2368. X    return(localize(objdub(mydpy->turtx)));
  2369. X}
  2370. X
  2371. Xstruct object *ycor()
  2372. X{
  2373. X    tcheck();
  2374. X    return(localize(objdub(mydpy->turty)));
  2375. X}
  2376. X
  2377. Xstruct object *heading()
  2378. X{
  2379. X    tcheck();
  2380. X    return(localize(objdub(posangle(mydpy->turth))));
  2381. X}
  2382. X
  2383. Xstruct object *getpen()
  2384. X{
  2385. X    tcheck();
  2386. X    return(localize(objint(color)));
  2387. X}
  2388. X
  2389. Xstruct object *setscrunch(new)
  2390. Xstruct object *new;
  2391. X{
  2392. X    tcheck();
  2393. X    yscrunch = ncheck(new);
  2394. X    return ((struct object *)(-1));
  2395. X}
  2396. X
  2397. Xstruct object *scrunch() {
  2398. X    tcheck();
  2399. X    return(localize(objdub(yscrunch)));
  2400. X}
  2401. X
  2402. Xpenup() {
  2403. X#ifdef FLOOR
  2404. X    int i;
  2405. X
  2406. X    if (turtdes>0) {
  2407. X        i = 'P'+0400;
  2408. X        write(turtdes,&i,2);
  2409. X        return;
  2410. X    }
  2411. X#endif FLOOR
  2412. X    tcheck();
  2413. X    pendown = 0;
  2414. X    (*mydpy->state)('U');
  2415. X}
  2416. X
  2417. Xcmpendown() {
  2418. X#ifdef FLOOR
  2419. X    int i;
  2420. X
  2421. X    if (turtdes>0) {
  2422. X        i = 'P';
  2423. X        write(turtdes,&i,2);
  2424. X        return;
  2425. X    }
  2426. X#endif FLOOR
  2427. X    tcheck();
  2428. X    pendown = 1;
  2429. X    penerase = 0;
  2430. X    (*mydpy->state)('D');
  2431. X}
  2432. X
  2433. Xcmpenerase() {
  2434. X    tcheck();
  2435. X    pendown = penerase = 1;
  2436. X    (*mydpy->state)('E');
  2437. X}
  2438. X
  2439. Xpenreverse() {
  2440. X    tcheck();
  2441. X    pendown = 1;
  2442. X    penerase = 2;
  2443. X    (*mydpy->state)('R');
  2444. X}
  2445. X
  2446. Xclearscreen() {
  2447. X    tcheck();
  2448. X    (*mydpy->txtchk)();
  2449. X    printf(mydpy->clear);
  2450. X    mydpy->turtx = mydpy->turty = mydpy->turth = 0.0;
  2451. X    (*mydpy->state)('c');
  2452. X    if (shown) (*mydpy->drawturt)(0);
  2453. X}
  2454. X
  2455. Xwipeclean() {
  2456. X    tcheck();
  2457. X    (*mydpy->txtchk)();
  2458. X    printf(mydpy->clear);
  2459. X    (*mydpy->state)('w');
  2460. X    if (shown) (*mydpy->drawturt)(0);
  2461. X}
  2462. X
  2463. Xfullscreen() {
  2464. X    tcheck();
  2465. X    (*mydpy->state)('f');
  2466. X    textmode = 0;
  2467. X}
  2468. X
  2469. Xsplitscreen() {
  2470. X    tcheck();
  2471. X    (*mydpy->state)('s');
  2472. X    textmode = 0;
  2473. X}
  2474. X
  2475. Xtextscreen() {
  2476. X    tcheck();
  2477. X    (*mydpy->state)('t');
  2478. X    textmode++;
  2479. X}
  2480. X
  2481. Xshowturtle() {
  2482. X    tcheck();
  2483. X    (*mydpy->txtchk)();
  2484. X    if (!shown) (*mydpy->drawturt)(0);
  2485. X    shown = 1;
  2486. X    (*mydpy->state)('S');
  2487. X}
  2488. X
  2489. Xhideturtle() {
  2490. X    tcheck();
  2491. X    (*mydpy->txtchk)();
  2492. X    if (shown) (*mydpy->drawturt)(1);
  2493. X    shown = 0;
  2494. X    (*mydpy->state)('H');
  2495. X}
  2496. X
  2497. Xstruct object *penmode() {
  2498. X    static char *pens[] = {"pendown","penerase","penreverse"};
  2499. X
  2500. X    tcheck();
  2501. X    if (pendown) return(localize(objcpstr(pens[penerase])));
  2502. X    return(localize(objcpstr("penup")));
  2503. X}
  2504. X
  2505. Xstruct object *shownp() {
  2506. X    tcheck();
  2507. X    return(torf(shown));
  2508. X}
  2509. X
  2510. Xstruct object *towardsxy(x,y)
  2511. Xstruct object *x,*y;
  2512. X{
  2513. X    NUMBER dx,dy;
  2514. X
  2515. X    tcheck();
  2516. X    dx = ncheck(x);
  2517. X    dy = ncheck(y);
  2518. X    return(localize(objdub(posangle((double)180.0*
  2519. X        atan2(dx-(mydpy->turtx),dy-(mydpy->turty))/3.141592654))));
  2520. X}
  2521. X
  2522. X#endif
  2523. X
  2524. END_OF_turtle.c
  2525. if test 9873 -ne `wc -c <turtle.c`; then
  2526.     echo shar: \"turtle.c\" unpacked with wrong size!
  2527. fi
  2528. # end of overwriting check
  2529. fi
  2530. echo shar: End of archive 3 \(of 6\).
  2531. cp /dev/null ark3isdone
  2532. MISSING=""
  2533. for I in 1 2 3 4 5 6 ; do
  2534.     if test ! -f ark${I}isdone ; then
  2535.     MISSING="${MISSING} ${I}"
  2536.     fi
  2537. done
  2538. if test "${MISSING}" = "" ; then
  2539.     echo You have unpacked all 6 archives.
  2540.     echo "Now see the README"
  2541.     rm -f ark[1-9]isdone
  2542. else
  2543.     echo You still need to unpack the following archives:
  2544.     echo "        " ${MISSING}
  2545. fi
  2546. ##  End of shell archive.
  2547. exit 0
  2548.